home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / c-tools / vbcc / machines / amiga68k / frontend / vc.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-22  |  11.4 KB  |  346 lines

  1. /*  Frontend fuer vbcc Amiga-Version        */
  2. /*  (c) in 1995 by Volker Barthelmann       */
  3. /*  benutzt viel mehr Speicher als noetig,  */
  4. /*  um sicher zu gehen, ohne gross          */
  5. /*  rumzurechnen                            */
  6. /*  Wildcards erst ab dos.library>=36       */
  7.  
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <dos/dos.h>
  12. #include <dos/dosasl.h>
  13. #include <exec/libraries.h>
  14. #include <clib/dos_protos.h>
  15.  
  16. extern struct Library *DOSBase;
  17.  
  18. struct NameList{
  19.     struct NameList *next;
  20.     char *obj;
  21. } *first_obj=0,*last_obj=0,*first_scratch=0,*last_scratch=0;
  22.  
  23. /*  Limit fuer Laenge der Namen (wegen Wildcards)   */
  24. #define NAMEBUF 1000
  25. #define USERLIBS 1000
  26.  
  27. /*  Ab dieser Laenge werden Objektfiles nicht direkt uebergeben,    */
  28. /*  sondern aus einem File an den Linker uebergeben                 */
  29. #define MAXCLEN 500
  30.  
  31. #define NOSTDLIB 512
  32. #define VERBOSE 256
  33. #define VERYVERBOSE 128
  34. #define KEEPSCRATCH 64
  35.  
  36. #define PPSRC 1
  37. #define CCSRC 2
  38. #define ASSRC 3
  39. #define OBJ 4
  40.  
  41. /*  Namen der einzelnen Phasen  */
  42. char *ppname="vcpp -Ivinclude: %s >%s",
  43.      *ccname="vbcc -quiet ",
  44.      *asname="FreePhxAss quiet %s to %s",
  45.      *ldname="PhxLnk vlib:startup.o %s lib %s vlib:vc.lib vlib:amiga.lib to %s",
  46.      *l2name="PhxLnk %s %s to %s",
  47.      *rmname="delete quiet %s";
  48. /*  dasselbe fuer VERBOSE   */
  49. char *ppv="vcpp -Ivinclude: %s >%s",
  50.      *ccv="vbcc ",
  51.      *asv="FreePhxAss %s to %s",
  52.      *ldv="PhxLnk vlib:startup.o %s %s vlib:vc.lib vlib:amiga.lib to %s",
  53.      *l2v="PhxLnk %s %s to %s",
  54.      *rmv="delete %s";
  55.  
  56. /*  String fuer die Default libraries   */
  57. char userlibs[USERLIBS];
  58. char *nomem="Not enough memory!\n";
  59.  
  60. char *destname="a.out";
  61. char namebuf[NAMEBUF+1];
  62.  
  63. char *config;
  64. char **confp;
  65.  
  66. int typ(char *);
  67. char *add_suffix(char *,char *);
  68. void raus(int);
  69.  
  70. char *command,*options,*linkcmd,*objects,*libs,*ppopts;
  71. struct AnchorPath *ap;
  72.  
  73. int linklen=10,flags=0;
  74.  
  75. void free_namelist(struct NameList *p)
  76. {
  77.     struct NameList *m;
  78.     while(p){
  79.         m=p->next;
  80.         if(flags&VERYVERBOSE){
  81.             puts("free p->obj");
  82.             if(!p->obj) puts("IS ZERO!!"); else puts(p->obj);
  83.         }
  84.         free((void *)p->obj);
  85.         if(flags&VERYVERBOSE){puts("free p"); if(!p) puts("IS ZERO!!");}
  86.         free((void *)p);
  87.         p=m;
  88.     }
  89. }
  90. void del_scratch(struct NameList *p)
  91. {
  92.     while(p){
  93.         sprintf(command,rmname,p->obj);
  94.         if(flags&VERBOSE) printf("%s\n",command);
  95.         if(system(command)){printf("%s failed\n",command);raus(20);}
  96.         p=p->next;
  97.     }
  98. }
  99. void raus(int rc)
  100. {
  101.     if(confp)   free(confp);
  102.     if(config)  free(config);
  103.     if(objects) free(objects);
  104.     if(libs)    free(libs);
  105.     if(command) free(command);
  106.     if(ppopts)  free(ppopts);
  107.     if(options) free(options);
  108.     if(linkcmd) free(linkcmd);
  109.     if(ap) free(ap);
  110.     free_namelist(first_obj);
  111.     free_namelist(first_scratch);
  112.     exit(rc);
  113. }
  114. void add_name(char *obj,struct NameList **first,struct NameList **last)
  115. {
  116.     struct NameList *new;
  117.     if(flags&VERYVERBOSE) printf("add_name: %s\n",obj);
  118.     if(!(new=(struct NameList *)malloc(sizeof(struct NameList))))
  119.         {printf(nomem);raus(20);}
  120.     if(!(new->obj=(char *)malloc(strlen(obj)+1)))
  121.         {free((void *)new);printf(nomem);raus(20);}
  122.     if(first==&first_obj) linklen+=strlen(obj)+1;
  123.     strcpy(new->obj,obj);
  124.     new->next=0;
  125.     if(!*first){
  126.         *first=*last=new;
  127.     }else{
  128.         (*last)->next=new;*last=new;
  129.     }
  130. }
  131. int read_config(void)
  132. {
  133.     BPTR l;struct FileInfoBlock fib;int i,count;
  134.     long size;BPTR file;char *configname="ENV:vc.config",*p;
  135.     l=Lock(configname,-2);
  136.     if(!l){configname="VBCC:vc.config";l=Lock(configname,-2);}
  137.     if(!l) return(0);
  138.     if(!Examine(l,&fib)){puts("Examine() failed!");raus(EXIT_FAILURE);}
  139.     size=fib.fib_Size;
  140.     config=malloc(size);
  141.     if(!config){printf(nomem);raus(EXIT_FAILURE);}
  142.     UnLock(l);
  143.     file=Open(configname,MODE_OLDFILE);
  144.     if(!file) return(0);
  145.     size=Read(file,config,size);
  146.     Close(file);
  147.     count=0;p=config;
  148.     while(*p&&p<config+size){
  149.         count++;
  150.         while(*p!='\n'&&p<config+size) p++;
  151.         if(*p=='\n') *p++=0;
  152.     }
  153.     confp=malloc(count*sizeof(char *));
  154.     for(p=config,i=0;i<count;i++){
  155.         confp[i]=p;
  156.         while(*p) p++;
  157.         p++;
  158.     }
  159.     return(count);
  160. }
  161.  
  162. int main(int argc,char *argv[])
  163. {
  164.     int i,opt=1,len=10,pm,count;char *parm;
  165.     char oldfile[NAMEBUF+2];
  166.     count=read_config();
  167.     if(pm=DOSBase->lib_Version>=36){
  168.         if(ap=(struct AnchorPath *)calloc(sizeof(struct AnchorPath)+NAMEBUF,1))
  169.             {ap->ap_Strlen=NAMEBUF;ap->ap_BreakBits=0;} else pm=0;
  170.     }
  171.     for(i=1;i<argc+count;i++){
  172.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  173. /*        printf("Parameter %d=%s\n",i,parm);*/
  174.         if(!strncmp(parm,"-pp=",4)){ppname=parm+4;*parm=0;}
  175.         if(!strncmp(parm,"-as=",4)){asname=parm+4;*parm=0;}
  176.         if(!strncmp(parm,"-ld=",4)){ldname=parm+4;*parm=0;}
  177.         if(!strncmp(parm,"-l2=",4)){l2name=parm+4;*parm=0;}
  178.         if(!strncmp(parm,"-rm=",4)){rmname=parm+4;*parm=0;}
  179.         if(!strncmp(parm,"-ppv=",5)){ppv=parm+5;*parm=0;}
  180.         if(!strncmp(parm,"-asv=",5)){asv=parm+5;*parm=0;}
  181.         if(!strncmp(parm,"-ldv=",5)){ldv=parm+5;*parm=0;}
  182.         if(!strncmp(parm,"-l2v=",5)){l2v=parm+5;*parm=0;}
  183.         if(!strncmp(parm,"-rmv=",5)){rmv=parm+5;*parm=0;}
  184.         if(!strcmp(parm,"-E")) {flags|=CCSRC;*parm=0;}
  185.         if(!strcmp(parm,"-S")) {flags|=ASSRC;*parm=0;}
  186.         if(!strcmp(parm,"-c")) {flags|=OBJ;*parm=0;}
  187.         if(!strcmp(parm,"-v")) {flags|=VERBOSE;*parm=0;}
  188.         if(!strcmp(parm,"-k")) {flags|=KEEPSCRATCH;*parm=0;}
  189.         if(!strcmp(parm,"-vv")) {flags|=VERBOSE|VERYVERBOSE;*parm=0;}
  190.         if(!strcmp(parm,"-nostdlib")) {flags|=NOSTDLIB;*parm=0;}
  191.         if(!strncmp(parm,"-O",2)){
  192.             if(parm[2]=='0') opt=0;
  193.             if(parm[2]=='1'||parm[2]==0) opt=991;
  194.             if(parm[2]=='2') opt=1023;
  195.             if(parm[2]>='3') opt=~0;
  196.             if(parm[2]=='=') opt=atoi(&parm[3]);
  197.             *parm=0;
  198.         }
  199.         if(!strcmp(parm,"-o")&&i<argc-1) {
  200.             *argv[i++]=0;destname=argv[i];
  201.             argv[i]="";continue;
  202.         }
  203.         if(parm[0]=='-'&&parm[1]=='l'){
  204.             if((strlen(userlibs)+strlen(parm)+15)>=USERLIBS){puts("Userlibs too long");exit(20);}
  205.             strcat(userlibs," vlib:");
  206.             strcat(userlibs,parm+2);
  207.             strcat(userlibs,".lib");
  208.             *parm=0;continue;
  209.         }
  210.         len+=strlen(parm)+10;
  211.     }
  212.     if(flags&VERBOSE) printf("vc frontend for vbcc (c) in 1995 by Volker Barthelmann\n");
  213.     if(!(flags&7)) flags|=5;
  214.     if(flags&VERYVERBOSE){ppname=ppv;ccname=ccv;asname=asv;ldname=ldv;rmname=rmv;l2name=l2v;}
  215.     if(flags&NOSTDLIB){ldname=l2name;}
  216.     /*  Nummer sicher...    */
  217.     len+=strlen(ppname)+strlen(ccname)+strlen(asname)+strlen(rmname)+strlen(userlibs)+NAMEBUF;
  218.     if(!(command=malloc(len))){printf(nomem);raus(20);}
  219.     if(!(options=malloc(len))){printf(nomem);raus(20);}
  220.     if(!(ppopts=malloc(len))){printf(nomem);raus(20);}
  221.     *options=0;*ppopts=0;
  222.     for(i=1;i<argc+count;i++){
  223.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  224.         if(*parm=='-'){
  225.             if(parm[1]!='D'&&parm[1]!='I'){
  226.                 strcat(options,parm);strcat(options," ");
  227.             }else{
  228.                 strcat(ppopts,parm);strcat(ppopts," ");
  229.             }
  230.         }
  231.     }
  232.     if(flags&VERYVERBOSE) printf("flags=%d opt=%d len=%d\n",flags,opt,len);
  233.     namebuf[0]='\"';
  234.     for(i=1;i<argc;i++){
  235.         int t,j;char *file;BPTR lock;
  236.         if(i<argc) parm=argv[i]; else parm=confp[i-argc];
  237.         if(*parm=='-'||!*parm) continue;
  238.         if(flags&VERYVERBOSE) printf("Argument %d:%s\n",i,parm);
  239.         if(pm) if(MatchFirst(parm,ap)) {printf("No match for %s\n",parm);continue;}
  240.         do{
  241.             if(pm) file=(char *)&ap->ap_Buf[0]; else file=parm;
  242.             t=typ(file);
  243.             if(pm&&(lock=Lock(file,-2))){
  244.                 NameFromLock(lock,namebuf+1,NAMEBUF-2);
  245.                 strcat(namebuf,"\"");
  246.                 file=namebuf;
  247.                 UnLock(lock);
  248.             }else{
  249.                 strcpy(namebuf+1,file);
  250.                 strcat(namebuf,"\"");
  251.                 file=namebuf;
  252.             }
  253.             if(flags&VERYVERBOSE) printf("File %s=%d\n",file,t);
  254.             for(j=t;j<(flags&7);j++){
  255.                 if(j==OBJ){ if(j==t) add_name(file,&first_obj,&last_obj);
  256.                             continue;}
  257.                 strcpy(oldfile,file);
  258.                 if(j==PPSRC){
  259.                     file=add_suffix(file,".i");
  260.                     sprintf(command,ppname,ppopts,oldfile,file);
  261.                     if((flags&7)!=CCSRC) add_name(file,&first_scratch,&last_scratch);
  262.                 }
  263.                 if(j==CCSRC){
  264.                     file=add_suffix(file,".asm");
  265.                     sprintf(command,"%s -O=%-4d %s %s",ccname,opt,options,oldfile);
  266.                     if((flags&7)!=ASSRC) add_name(file,&first_scratch,&last_scratch);
  267.                 }
  268.                 if(j==ASSRC){
  269.                     file=add_suffix(file,".o");
  270.                     sprintf(command,asname,oldfile,file);
  271.                     add_name(file,&first_obj,&last_obj);
  272.                     if((flags&7)!=OBJ) add_name(file,&first_scratch,&last_scratch);
  273.                 }
  274.                 if(flags&VERBOSE) printf("%s\n",command);
  275.                 if(system(command)){printf("%s failed\n",command);raus(20);}
  276.             }
  277.         }while(pm&&!MatchNext(ap));
  278.         if(pm) MatchEnd(ap);
  279.     }
  280.     if((flags&7)>OBJ){
  281.     /*  Zu Executable linken    */
  282.         struct NameList *p;
  283.         BPTR objfile=0;
  284.         objects=malloc(linklen);
  285.         if(!objects){printf(nomem);raus(EXIT_FAILURE);}
  286.         linklen+=strlen(ldname)+strlen(destname)+strlen(userlibs)+10;
  287.         if(flags&VERYVERBOSE) printf("linklen=%d\n",linklen);
  288.         if(!(linkcmd=(char *)malloc(linklen))){printf(nomem);raus(20);}
  289.         p=first_obj;
  290.         if(linklen>=MAXCLEN){
  291.             strcpy(objects+1,tmpnam(0));
  292.             *objects='@';
  293.             if(!(objfile=Open(objects+1,MODE_NEWFILE))){
  294.                 printf("Could not open <%s>!\n",objects+1);
  295.                 raus(20);
  296.             }
  297.         }else *objects=0;
  298.         while(p){
  299.             if(p->obj){
  300.                 if(linklen>=MAXCLEN){
  301.                     Write(objfile,p->obj,strlen(p->obj));
  302.                     Write(objfile,"\n",1);
  303.                 }else{
  304.                     strcat(objects,p->obj);strcat(objects," ");
  305.                 }
  306.             }
  307.             p=p->next;
  308.         }
  309.         if(objfile) Close(objfile);
  310.         if(*objects){
  311.             sprintf(linkcmd,ldname,objects,userlibs,destname);
  312.             if(flags&VERBOSE) printf("%s\n",linkcmd);
  313.             /*  hier wird objfile bei Fehler nicht geloescht    */
  314.             if(system(linkcmd)){printf("%s failed\n",linkcmd);raus(20);}
  315.         }else puts("No objects to link");
  316.         if(objfile) DeleteFile(objects+1);
  317.     }
  318.     if(!(flags&KEEPSCRATCH)) del_scratch(first_scratch);
  319.     raus(0);
  320. }
  321.  
  322. int typ(char *p)
  323. {
  324.     p=strrchr(p,'.');
  325.     if(!p) return(5);
  326.     if(!strcmp(p,".c")) return(PPSRC);
  327.     if(!strcmp(p,".i")) return(CCSRC);
  328.     if(!strcmp(p,".s")) return(ASSRC);
  329.     if(!strcmp(p,".asm")) return(ASSRC);
  330.     if(!strcmp(p,".o")) return(OBJ);
  331.     if(!strcmp(p,".obj")) return(OBJ);
  332.     return(5);
  333. }
  334.  
  335. char *add_suffix(char *s,char *suffix)
  336. {
  337.     static char str[NAMEBUF+3],*p;
  338.     if(strlen(s)+strlen(suffix)>NAMEBUF){printf("string too long\n");raus(20);}
  339.     if(s!=str) strcpy(str,s);
  340.     p=strrchr(str,'.');
  341.     if(!p) p=str+strlen(s);
  342.     strcpy(p,suffix);
  343.     strcat(p,"\"");
  344.     return(str);
  345. }
  346.